package flexconsole.utils {
	import flexunit.framework.Assert;
	
	import mx.utils.StringUtil;
	
	public class LogXMLUtil {
		static public const UNKNOWN_VALUE:String = 'UNKNOWN';
		
		static public function fromXML(xml:XML):String {
			Assert.assertNotNull(xml);
			return StringUtil.substitute("{0} [{1}] {2} {3}", attributeSafe(xml, "@date"), attributeSafe(xml, "@level"), attributeSafe(xml, "@category"), xml[0].toString());
		}
		
		static public function toXML(value:String):XML {
			Assert.assertNotNull(value);
			//   Log message looks like this: 6/29/2010 17:14:05.731 [DEBUG] flexconsole.model.ConfigProxy setValue(connected, true)
			var dteStr:String;
			var levelStr:String = UNKNOWN_VALUE;
			var categoryStr:String = UNKNOWN_VALUE;
			var regex:RegExp =  /([^\[]*)(\[\w*\])(.*)/gim;
			var matches:Array = regex.exec(value);
			var msg:String;
			
			if (matches) {
				try {
					dteStr = StringUtil.trim(matches[1]);
					levelStr = StringUtil.trim(matches[2]);
					var restStr:String = StringUtil.trim(matches[3]);
					//	restvalue may look something like this:
					//	'mx.messaging.Channel 'null' channel sending message:'
					regex = /^([\w\.]*)(.*)$/gi;
					matches = regex.exec(restStr);
					
					if (matches) {
						categoryStr = matches[1];
						restStr = matches[2];
					}
					msg = StringUtil.trim(value.substr(value.indexOf(restStr)));
				} catch (e:Error) {
					//	ignore
				}
			}
			
			if (!msg) {
				msg = value;
			}
			
			if (!dteStr) {
				dteStr = formatDatetime(new Date());
			}
			
			if (levelStr.substr(0, 1) == '[') {
				levelStr = levelStr.substr(1);
			}
			
			if (levelStr.substr(levelStr.length - 1, 1) == ']') {
				levelStr = levelStr.substr(0, levelStr.length - 1);
			}
			levelStr.replace(/\[|\]/gi, '');
			var xml:XML = new XML("<log />");
			xml.@date = dteStr;
			xml.@category = categoryStr;
			xml.@level = levelStr;
			xml.appendChild(msg);
			return xml;
		}
		
		/**
		 * Returns a LineFormattedTarget style of datetime.
		 * @param d
		 * @return
		 *
		 */
		static public function formatDatetime(d:Date):String {
			var fieldSeparator:String = ' ';
			var value:String = Number(d.getMonth() + 1).toString() + "/" + d.getDate().toString() + "/" + d.getFullYear() + fieldSeparator;
			value += padTime(d.getHours()) + ":" + padTime(d.getMinutes()) + ":" + padTime(d.getSeconds()) + "." + padTime(d.getMilliseconds(), true) + fieldSeparator;
			return value;
		
		}
		
		/**
		 * @private
		 *
		 */
		static public function padTime(num:Number, millis:Boolean = false):String {
			if (millis) {
				if (num < 10)
					return "00" + num.toString();
				else if (num < 100)
					return "0" + num.toString();
				else
					return num.toString();
			} else {
				return num > 9 ? num.toString() : "0" + num.toString();
			}
		}
		
		static private function attributeSafe(xml:XML, attributeName:String):String {
			return xml.hasOwnProperty(attributeName) ? xml[attributeName] : "x";
		}
	
	}
}